#ifndef __DOUBLELINKLIST_H__
#define __DOUBLELINKLIST_H__
#include<iostream>
template<typename T>
class DoubleLinklist
{
public:
    DoubleLinklist();
    void InsertTail(const T&element);
    template <typename U>
    friend std::ostream&operator<<(std::ostream& os,const DoubleLinklist<U>&a);
    void RemoveByIndex(int index);
    T& Gethead()
    {   if(size==0)
            throw std::out_of_range("链表为空，无法取出头部元素！");
        return head->next->data;
    }
    int Size(){return size;}
     T& GetTail()
    {   
        return tail->data;
    }
private:
    struct Node
    {
        Node(const T&element)
        {
            next=prev=nullptr;
            data=element;
        }
        T data;
        Node*next;
        Node*prev;
    };
    Node*head;
    Node*tail;
    int size;
};
template<typename T>
DoubleLinklist<T>::DoubleLinklist():size(0)
{
    head=tail=new Node(T());
}


template <typename T>
void DoubleLinklist<T>::InsertTail(const T&element)
{
    tail->next = new Node(element);
    tail->next->prev = tail;
    tail = tail->next;
    size++;
}

template <typename T>
inline void DoubleLinklist<T>::RemoveByIndex(int index)
{
    if (index < 0 || index >= size)
    {
        return;
    }
    Node *TP = head;
    for (int i = 0; i < index; i++)
    {
        TP = TP->next;
    }
    Node *freeNode = TP->next;
    TP->next = freeNode->next;
    if (freeNode == tail)
    {
        tail = tail->prev;
    }
    else
    {
        freeNode->next->prev = TP;
    }
    delete freeNode;
    size--;    
}

template <typename T>
inline std::ostream&operator<<(std::ostream& os,const DoubleLinklist<T>&a)
{   //typename 声明后面跟随的模板是一个类型
 typename DoubleLinklist<T>::Node*travePoint =a.head->next; // 存有效数据的第一个节点
    while (travePoint != nullptr)
    {
        std::cout << travePoint->data << "  "; // 打印数据域
        travePoint = travePoint->next;
    }
    std::cout << std::endl;
    return os;
}















#endif